#include <assert.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <limits.h>

typedef struct
{
    uint32_t result;
    uint32_t error_code;
} addition_result_t;

extern addition_result_t
    addition(uint32_t a, uint32_t b);

void assert_addition(uint32_t a, uint32_t b, addition_result_t expected_result)
{
    addition_result_t result = addition(a, b);

    assert(expected_result.result == result.result);
    assert(expected_result.error_code == result.error_code);
}

void test_api()
{
    {
        addition_result_t expected_result = {.result = 0, .error_code = 0};
        assert_addition(0, 0, expected_result);
    }
    {
        addition_result_t expected_result = {.result = 1, .error_code = 0};
        assert_addition(0, 1, expected_result);
    }
    {
        addition_result_t expected_result = {.result = UINT_MAX, .error_code = 0};
        assert_addition(0, UINT_MAX, expected_result);
    }
    {
        addition_result_t expected_result = {.result = 1, .error_code = 0};
        assert_addition(1, 0, expected_result);
    }
    {
        addition_result_t expected_result = {.result = 2, .error_code = 0};
        assert_addition(1, 1, expected_result);
    }
    {
        addition_result_t expected_result = {.result = UINT_MAX, .error_code = 0};
        assert_addition(1, UINT_MAX - 1, expected_result);
    }
    {
        addition_result_t expected_result = {.result = 0, .error_code = 1};
        assert_addition(1, UINT_MAX, expected_result);
    }
}

int main(void)
{
    addition_result_t result = addition(1, 2);
    printf("(result: %" PRIu32 ", error_code: %" PRIu32 ")\n",
           result.result,
           result.error_code);

    test_api();

    return 0;
}
